﻿using System;
using System.Linq;
using Helpers;
using MarriageFertility.Helpers;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.Party;

namespace MarriageFertility.Actions;

public static class CustomerMarriageAction
{
    public static void ForceMarry(this Hero maleHero, Hero femaleHero)
    {
        try
        {
            Helper.ChangeCompanionOccupation(femaleHero);
            MarriageAction.Apply(maleHero, femaleHero);
            AddHeroToParty(femaleHero, MobileParty.MainParty);
        }
        catch (Exception e)
        {
            Log.ErrorMessage(e.Message);
            Log.ErrorMessage(e.StackTrace);
        }
    }
    public static void ForceNpcMarry(this Hero firstHero, Hero secondHero, bool showNotification)
    {
        firstHero.Spouse = secondHero;
        secondHero.Spouse = firstHero;
        ChangeRelationAction.ApplyRelationChangeBetweenHeroes(firstHero, secondHero,
            Campaign.Current.Models.MarriageModel.GetEffectiveRelationIncrease(firstHero, secondHero), false);
        Clan clanAfterMarriage = Campaign.Current.Models.MarriageModel.GetClanAfterMarriage(firstHero, secondHero);
        if (firstHero.Clan != clanAfterMarriage)
            HandleClanChangeAfterMarriageForHero(firstHero, clanAfterMarriage);
        else
            HandleClanChangeAfterMarriageForHero(secondHero, clanAfterMarriage);

        ChangeRomanticStateAction.Apply(firstHero, secondHero, Romance.RomanceLevelEnum.Marriage);
        CampaignEventDispatcher.Instance.OnHeroesMarried(firstHero, secondHero, showNotification);
    }

    private static void HandleClanChangeAfterMarriageForHero(Hero hero, Clan clanAfterMarriage)
    {
        Clan clan = hero.Clan;
        if (hero.GovernorOf != null)
            ChangeGovernorAction.RemoveGovernorOf(hero);
        if (hero.PartyBelongedTo != null)
        {
            if (clan.Kingdom != clanAfterMarriage.Kingdom)
            {
                if (hero.PartyBelongedTo.Army != null)
                {
                    if (hero.PartyBelongedTo.Army.LeaderParty == hero.PartyBelongedTo)
                        DisbandArmyAction.ApplyByUnknownReason(hero.PartyBelongedTo.Army);
                    else
                        hero.PartyBelongedTo.Army = null;
                }

                FactionHelper.FinishAllRelatedHostileActionsOfNobleToFaction(hero,
                    (IFaction)clanAfterMarriage.Kingdom ?? clanAfterMarriage);
            }

            MakeHeroFugitiveAction.Apply(hero);
        }

        hero.Clan = clanAfterMarriage;
        foreach (Hero hero1 in clan.Heroes)
            hero1.UpdateHomeSettlement();
        foreach (Hero hero2 in clanAfterMarriage.Heroes)
            hero2.UpdateHomeSettlement();
    }
    
    private static void AddHeroToParty(Hero hero, MobileParty mobileParty)
    {
        if(!mobileParty.MemberRoster.Contains(hero.CharacterObject)) TeleportHeroAction.ApplyImmediateTeleportToParty(hero, mobileParty);
    }
    

    public static bool IsSpouse(this Hero hero, Hero otherHero)
    {
        return hero != null && otherHero != null &&
               (hero.Spouse == otherHero || hero.ExSpouses.Contains(otherHero));
    }

    public static void ChangePrisonerToParty(Hero hero)
    {
        if (hero == null || !hero.IsPrisoner || !MobileParty.MainParty.PrisonRoster.Contains(hero.CharacterObject))
            return;
        MobileParty.MainParty.PrisonRoster.RemoveIf(obj =>
            obj.Character.IsHero && obj.Character.HeroObject == hero);
        hero.ChangeState(Hero.CharacterStates.Active);
        MobileParty.MainParty.AddElementToMemberRoster(hero.CharacterObject, 1);
    }
}